﻿using System;
using System.Collections.Generic;
using System.IO;
using GeoAPI.Geometries;

namespace NetTopologySuite.GeometriesGraph
{
	public class EdgeIntersectionList
	{
		public EdgeIntersectionList(Edge edge)
		{
			this.edge = edge;
		}

		public int Count
		{
			get
			{
				return this.nodeMap.Count;
			}
		}

		public EdgeIntersection Add(Coordinate intPt, int segmentIndex, double dist)
		{
			EdgeIntersection edgeIntersection = new EdgeIntersection(intPt, segmentIndex, dist);
			EdgeIntersection result;
			if (this.nodeMap.TryGetValue(edgeIntersection, out result))
			{
				return result;
			}
			this.nodeMap[edgeIntersection] = edgeIntersection;
			return edgeIntersection;
		}

		public IEnumerator<EdgeIntersection> GetEnumerator()
		{
			return this.nodeMap.Values.GetEnumerator();
		}

		public bool IsIntersection(Coordinate pt)
		{
			IEnumerator<EdgeIntersection> enumerator = this.nodeMap.Values.GetEnumerator();
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.Coordinate.Equals(pt))
					{
						return true;
					}
				}
			}
			return false;
		}

		public void AddEndpoints()
		{
			int num = this.edge.Points.Length - 1;
			this.Add(this.edge.Points[0], 0, 0.0);
			this.Add(this.edge.Points[num], num, 0.0);
		}

		public void AddSplitEdges(IList<Edge> edgeList)
		{
			this.AddEndpoints();
			IEnumerator<EdgeIntersection> enumerator = this.GetEnumerator();
			enumerator.MoveNext();
			EdgeIntersection ei = enumerator.Current;
			while (enumerator.MoveNext())
			{
				EdgeIntersection edgeIntersection = enumerator.Current;
				Edge item = this.CreateSplitEdge(ei, edgeIntersection);
				edgeList.Add(item);
				ei = edgeIntersection;
			}
		}

		public Edge CreateSplitEdge(EdgeIntersection ei0, EdgeIntersection ei1)
		{
			int num = ei1.SegmentIndex - ei0.SegmentIndex + 2;
			Coordinate other = this.edge.Points[ei1.SegmentIndex];
			bool flag = ei1.Distance > 0.0 || !ei1.Coordinate.Equals2D(other);
			if (!flag)
			{
				num--;
			}
			Coordinate[] array = new Coordinate[num];
			int num2 = 0;
			array[num2++] = new Coordinate(ei0.Coordinate);
			for (int i = ei0.SegmentIndex + 1; i <= ei1.SegmentIndex; i++)
			{
				array[num2++] = this.edge.Points[i];
			}
			if (flag)
			{
				array[num2] = ei1.Coordinate;
			}
			return new Edge(array, new Label(this.edge.Label));
		}

		public void Write(StreamWriter outstream)
		{
			outstream.WriteLine("Intersections:");
			foreach (EdgeIntersection edgeIntersection in this)
			{
				edgeIntersection.Write(outstream);
			}
		}

		private readonly IDictionary<EdgeIntersection, EdgeIntersection> nodeMap = new SortedDictionary<EdgeIntersection, EdgeIntersection>();

		private readonly Edge edge;
	}
}
